{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"https://raw.githubusercontent.com/Qiskit/qiskit-tutorials/master/images/qiskit-heading.png\" alt=\"Note: In order for images to show up in this jupyter notebook you need to select File => Trusted Notebook\" width=\"500 px\" align=\"left\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Ask the Quantum 8-ball\n",
    "Sometimes we let chance decide. Quantum uncertainty is the cornerstone design feature of Quantum computers. Once the program is executed on a Quantum computer, you will receive the most unbiased random answer, a *True* chance that classical computers incapable to provide. Think about a question that can be answered \"yes or no\" and run the code. Quantum 8-ball returns one of the 8 possible answers to your question. You might be already familiar with some parts of the code used in other Qiskit tutorials.\n",
    "\n",
    "The latest version of this notebook is available on https://github.com/qiskit/qiskit-tutorial.\n",
    "\n",
    "***\n",
    "### Contributors\n",
    "Oleksii Lialka, MBA"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# begin with importing essential libraries for IBM Q\n",
    "from qiskit import IBMQ, BasicAer\n",
    "from qiskit import ClassicalRegister, QuantumRegister, QuantumCircuit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To obtain $2^3 = 8$ outcomes with the equal likelyhood we need to generate 3 qubits and put them into superposition using The Hadamard gate $H$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<qiskit.circuit.instructionset.InstructionSet at 0x116c96198>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# set up Quantum Register and Classical Register for 3 qubits\n",
    "q = QuantumRegister(3)\n",
    "c = ClassicalRegister(3)\n",
    "# Create a Quantum Circuit\n",
    "qc = QuantumCircuit(q, c)\n",
    "qc.h(q)\n",
    "qc.measure(q, c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Visualize the circuit. Note: you need LaTeX to make visualizations. Details: https://www.latex-project.org/latex3/"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"word-wrap: normal;white-space: pre;line-height: 15px;\">                         ┌───┐┌─┐\n",
       "q0_0: |0>────────────────┤ H ├┤M├\n",
       "                 ┌───┐┌─┐└───┘└╥┘\n",
       "q0_1: |0>────────┤ H ├┤M├──────╫─\n",
       "         ┌───┐┌─┐└───┘└╥┘      ║ \n",
       "q0_2: |0>┤ H ├┤M├──────╫───────╫─\n",
       "         └───┘└╥┘      ║       ║ \n",
       " c0_0: 0 ══════╬═══════╬═══════╩═\n",
       "               ║       ║         \n",
       " c0_1: 0 ══════╬═══════╩═════════\n",
       "               ║                 \n",
       " c0_2: 0 ══════╩═════════════════\n",
       "                                 </pre>"
      ],
      "text/plain": [
       "<qiskit.tools.visualization._text.TextDrawing at 0x116c77da0>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "qc.draw()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before we move on, let's assign predictions to interpret the outcomes. The particle can be observed in one of 8 states: [000, 001, 010, 011, 100, 101, 110, 111]. We link each state to the particular \"answer\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def answer(result):\n",
    "    for key in result.keys():\n",
    "        state = key\n",
    "    print('The Quantum 8-ball says:')\n",
    "    if state == '000':\n",
    "        print('It is certain.')\n",
    "    elif state == '001':\n",
    "        print('Without a doubt.')\n",
    "    elif state == '010':\n",
    "        print('Yes - definitely.')\n",
    "    elif state == '011':\n",
    "        print('Most likely.')\n",
    "    elif state == '100':\n",
    "        print(\"Don't count on it.\")\n",
    "    elif state == '101':\n",
    "        print('My reply is no.')\n",
    "    elif state == '110':\n",
    "        print('Very doubtful.')\n",
    "    else:\n",
    "        print('Concentrate and ask again.')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Simulation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, we launch the program on a classical computer you are currently using (or cloud service), launch one particle, interpret and display the result."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The Quantum 8-ball says:\n",
      "It is certain.\n"
     ]
    }
   ],
   "source": [
    "from qiskit import execute\n",
    "job = execute(qc, backend=BasicAer.get_backend('qasm_simulator'), shots=1)\n",
    "result = job.result().get_counts(qc)\n",
    "answer(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Try to run the code multiple times to obtain different answer. The simulation is mimiking the behavior of quantum computer. States of the particle are generated using pseudo-random numbers, which give you the impression of being random, yet they are following certain prescribed rules and algorithms. Classical machines, unlike quantum computers, are inherently incapable of producing true random numbers."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Running the program on real quantum computer"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We are almost set to run the program on a real quantum computer."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# load IBM Q account\n",
    "IBMQ.load_accounts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The least busy device: ibmqx4\n"
     ]
    }
   ],
   "source": [
    "# define the least busy device\n",
    "from qiskit.providers.ibmq import least_busy\n",
    "backend = least_busy(IBMQ.backends(simulator=False))\n",
    "print(\"The least busy device:\",backend.name())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Once we successfully loaded IBM Q account and connected to the least busy quantum computer, it's time to run the program on real device."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The Quantum 8-ball says:\n",
      "Yes - definitely.\n"
     ]
    }
   ],
   "source": [
    "job = execute(qc, backend=backend, shots=1)\n",
    "result = job.result().get_counts(qc)\n",
    "answer(result)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
